Attribute VB_Name = "modExternalChild"
'***************************************************************
' (c) Copyright 2000 Matthew J. Curland
'
' This file is from the CD-ROM accompanying the book:
' Advanced Visual Basic 6: Power Techniques for Everyday Programs
'   Author: Matthew Curland
'   Published by: Addison-Wesley, July 2000
'   ISBN: 0-201-70712-8
'   http://www.PowerVB.com
'
' You are entitled to license free distribution of any application
'   that uses this file if you own a copy of the book, or if you
'   have obtained the file from a source approved by the author. You
'   may redistribute this file only with express written permission
'   of the author.
'
' This file depends on:
'   References:
'     VBoostTypes6.olb (VBoost Object Types (6.0))
'     VBoost6.dll (VBoost Object Implementation (6.0))
'   Files:
'     VBoost.bas
'   Minimal VBoost conditionals:
'     VBOOST_INTERNAL = 1 : VBOOST_CUSTOM = 1 : VBOOST_CreateAggregate = 1
'   Conditional Compilation Values:
'     None
'
' This file is discussed in Chapter 6 and Appendix A.
'***************************************************************
Option Explicit

'CreateExternal is a specific version of the function shown in
'in Hierarchical Object Models section of Chapter 6. In this scenario,
'a Child object has a weak reference on its parent object. When the
'Child object is passed to an external client, it needs to protect its
'parent. This is easily done with CreateAggregate by establishing the
'child as a blindly aggregated object and the parent as a reference
'which isn't queried.
'
'Child is the main object, ParentPtr is the ObjPtr of its parent, and
'ExternalPtr is a member variable of Child.
Public Function CreateExternal(ByVal Child As IUnknown, ByVal ParentPtr As Long, ExternalPtr As Long) As IUnknown
Dim AggData(1) As AggregateData
Dim IIDs() As VBGUID
    If ExternalPtr Then
        VBoost.AssignAddRef CreateExternal, ExternalPtr
    Else
        'Defer all QueryInterface calls to the child
        With AggData(0)
            Set .pObject = Child
            .Flags = adIgnoreIIDs
        End With

        'Let the aggregator hold the parent reference for us, but
        'don't forward any QueryInterface calls to it.
        With AggData(1)
            VBoost.AssignAddRef .pObject, ParentPtr
            .Flags = adDontQuery
        End With

        Set CreateExternal = VBoost.CreateAggregate(AggData, IIDs, VarPtr(ExternalPtr))
    End If
End Function
